"""
Security utilities for the DingTalk Card Sender
"""
from pydantic import BaseModel, ValidationError, field_validator
from typing import Dict, Any, List
import html
import re
from typing import Dict, Any


def sanitize_input(input_str: str) -> str:
    """
    Sanitize user input to prevent XSS and other injection attacks
    """
    if input_str is None:
        return None
    
    # Remove potentially dangerous characters/sequences
    sanitized = html.escape(input_str)
    
    # Additional sanitization could be applied here
    # For example, remove script tags if input should not contain HTML
    sanitized = re.sub(r'<script.*?</script>', '', sanitized, flags=re.IGNORECASE | re.DOTALL)
    sanitized = re.sub(r'javascript:', '', sanitized, flags=re.IGNORECASE)
    sanitized = re.sub(r'on\w+\s*=', '', sanitized, flags=re.IGNORECASE)
    
    return sanitized


def validate_template_name(name: str) -> str:
    """
    Validate and sanitize template name
    """
    if not name or not isinstance(name, str):
        raise ValueError("Template name must be a non-empty string")
    
    # Check length
    if len(name) > 100:
        raise ValueError("Template name is too long (max 100 characters)")
    
    # Check for allowed characters (alphanumeric, underscore, hyphen, space)
    if not re.match(r'^[a-zA-Z0-9_\-\s]+$', name):
        raise ValueError("Template name contains invalid characters")
    
    return sanitize_input(name)


# Pydantic models for input validation
class SendCardRequest(BaseModel):
    """Model for validating send card requests"""
    msgtype: str
    text: dict = None
    link: dict = None
    markdown: dict = None
    actionCard: dict = None
    feedCard: dict = None
    oa: dict = None
    webhook_url: str = None
    secret: str = None
    
    @field_validator('msgtype')
    @classmethod
    def validate_msgtype(cls, v):
        allowed_types = ["text", "link", "markdown", "actionCard", "feedCard", "oa"]
        if v not in allowed_types:
            raise ValueError(f'msgtype must be one of {allowed_types}')
        return v
    
    @field_validator('webhook_url')
    @classmethod
    def validate_webhook_url(cls, v):
        if v:
            # Basic URL validation
            if not re.match(r'^https?://.+\..+', v):
                raise ValueError('Invalid webhook URL format')
        return v


class SaveTemplateRequest(BaseModel):
    """Model for validating save template requests"""
    content: Dict[str, Any]
    category: str = "默认分类"
    tags: list = []
    
    @field_validator('category')
    @classmethod
    def validate_category(cls, v):
        if len(v) > 50:
            raise ValueError('Category name is too long')
        return sanitize_input(v) if v else v
    
    @field_validator('tags')
    @classmethod
    def validate_tags(cls, v):
        if not isinstance(v, list):
            raise ValueError('Tags must be a list')
        if len(v) > 10:
            raise ValueError('Too many tags (max 10)')
        for tag in v:
            if not isinstance(tag, str) or len(tag) > 50:
                raise ValueError('Each tag must be a string with max 50 characters')
        return [sanitize_input(tag) for tag in v if tag]